package com.hcl.security.utils;

import java.io.IOException;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

/**
 * Json相关工具类
 */
public class JsonUtils {

	private static final ObjectMapper JSON_MAPPER;

	static {
		JSON_MAPPER = new ObjectMapper();
		// set DateTime default formatter "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
		JSON_MAPPER.registerModule(new JavaTimeModule());
		JSON_MAPPER.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
		JSON_MAPPER.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
	}

	/**
	 * JSON String 转化为对象
	 *
	 * @param jsonContent
	 *            json内容
	 * @param clazz
	 *            对象类型
	 */
	public static <T> T jsonToObject(String jsonContent, Class<T> clazz) {
		try {
			return JSON_MAPPER.readValue(jsonContent, clazz);
		} catch (IOException e) {
			throw new RuntimeException("can not convert [" + jsonContent
					+ "] to " + clazz.getName());
		}
	}

	/**
	 * JSON String 转化为对象
	 *
	 * @param jsonContent
	 *            json内容
	 * @param valueTypeRef
	 *            对象类型
	 */
	public static <T> T jsonToObject(String jsonContent,
			TypeReference<T> valueTypeRef) {
		try {
			return JSON_MAPPER.readValue(jsonContent, valueTypeRef);
		} catch (IOException e) {
			throw new RuntimeException("can not convert [" + jsonContent
					+ "] to " + valueTypeRef.getType());
		}
	}

	/**
	 * byte转化为对象
	 *
	 * @param byteContent
	 *            byte内容
	 * @param clazz
	 *            对象类型
	 */
	public static <T> T jsonToObject(byte[] byteContent, Class<T> clazz) {
		try {
			return JSON_MAPPER.readValue(byteContent, clazz);
		} catch (IOException e) {
			throw new RuntimeException(
					"can not convert bytes to " + clazz.getName());
		}
	}

	/**
	 * byte转化为对象
	 *
	 * @param byteContent
	 *            byte内容
	 * @param valueTypeRef
	 *            对象类型
	 */
	public static <T> T byteToObject(byte[] byteContent,
			TypeReference<T> valueTypeRef) {
		try {
			return JSON_MAPPER.readValue(byteContent, valueTypeRef);
		} catch (IOException e) {
			throw new RuntimeException(
					"can not convert bytes to " + valueTypeRef.getType());
		}
	}

	/**
	 * JSON String 转化为对象
	 *
	 * @param obj
	 *            目标对象
	 */
	public static String objectToJson(Object obj) {
		try {
			return JSON_MAPPER.writeValueAsString(obj);
		} catch (IOException e) {
			throw new RuntimeException("can not convert obj to json");
		}
	}

	/**
	 * 将Object类型的对象转换成指定类型
	 *
	 * @param obj
	 *            目标对象
	 * @param clazz
	 *            对象类型
	 */
	public static <T> T convertClass(Object obj, Class<T> clazz) {
		String objStr = objectToJson(obj);
		return jsonToObject(objStr, clazz);
	}
}
